from Ft.Rdf.Parsers.Versa.Processor import Processor
from myelin.server.lib.RdfQueryResolvers import UrlResolver, GraphResolver

from myelin.rdf.stores.ft import LimitAdapter

from nodetypes import config
from nodetypes.services import Query


class Service(object):    
    
    newProcessor = Processor
    newUrlResolver = staticmethod(UrlResolver.FromRepo)
    
    queryHelper = Query.Query()
    
    defaults = config.SERVICE_VERSA_DEFAULTS
    
        
    def fetchParams(self, context, source, params, errors):
        return params, errors
    
    def execute(self, context, source):
        
        params, errors = self.fetchParams(context, source, {}, {})
        eventData = context.event.data        
        eventData.params = params
        eventData.errors = errors
        
        if errors:
            return False
        
        nsMaps = {}
        error = self.queryHelper.splitNsMaps(params['nsmaps'], nsMaps)
        if error:
            #print "Error NsMaps: %s" % nsMaps
            #print "msg: %s" % error
            errors['nsmaps'] = unicode(error)
            return False
                
        repo = context.repo
        server = context.server
        dbDriver, dbDefaultGraph, dbGraphResolver, dbTextResolver = self.queryHelper.getDbSource(
            repo,
            eventData.config,
            context.account,
            context.acls,            
            context.defaults
        )
        
        from Ft.Rdf.Parsers.Versa import Constants
        
        try:            
            results = self.newProcessor(
                dbDriver, {
                    Constants.RESOLVER_URL : self.newUrlResolver(
                        repo,
                        None,
                        context.urlFormatter
                    ),
                    Constants.RESOLVER_GRAPH : dbGraphResolver,
                    Constants.RESOLVER_TEXT_INDEX : dbTextResolver,
                },
                dbDefaultGraph,
                server.defaults.server_id
            ).query(params['query'], nsMaps)
        except:
            if __debug__:
                import traceback
                print "An exception occured during Versa Service"
                traceback.print_exc()
            errors['query'] = u'syntax-error'
            return False
        
        eventData.results = results
        return True


#if __debug__:
#    def testSplit(nsString, nsMaps):
#        import re
#        nsMapPatSplit = re.compile(r'\s*([\w]+)\s*=\s*([\'\"]*)([^\"\'\s]+)\2\s*').split
#        
#        m = nsMapPatSplit(nsString)
#        if m:
#            l = len(m)
#            print "Size: %s" % l
#            print "m: %s" % m
#            
#            i = 0
#            while i+3 < l:
#                print i
#                if m[i]:
#                    return 'invalid-token'
#                ns = m[i+1]
#                if not ns:
#                    return 'invalid-ns'
#                url = m[i+3]
#                if not url:
#                    return 'invalid-url'
#                    break
#                print "ns=%s url=%s" % (ns, url)
#                nsMaps[ns] = url
#                i += 4
#            i -= l
#            print "i: %s" % str(i)
#            if i == -1:
#                print "m-1: %s" % m[-1]
#                if m[-1]:
#                    return 'invalid-token 2'
#            elif i < 4: # checks for garbage at the end
#                return 'invalid-token 3'


# cleanup
del config, \
    Query, \
    Processor, \
    UrlResolver
